home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / ARexxTools / fpl70.lha / src / caller.c next >
Encoding:
C/C++ Source or Header  |  1994-04-09  |  14.3 KB  |  523 lines

  1. /******************************************************************************
  2.  *                   FREXX PROGRAMMING LANGUAGE                  *
  3.  ******************************************************************************
  4.  
  5.  caller.c
  6.  
  7.  For FPL debugging...
  8.  Only part of the executable file version of FPL.
  9.  
  10.  *****************************************************************************/
  11.  
  12. /************************************************************************
  13.  *                                                                      *
  14.  * fpl.library - A shared library interpreting script langauge.         *
  15.  * Copyright (C) 1992-1994 FrexxWare                                    *
  16.  * Author: Daniel Stenberg                                              *
  17.  *                                                                      *
  18.  * This program is free software; you may redistribute for non          *
  19.  * commercial purposes only. Commercial programs must have a written    *
  20.  * permission from the author to use FPL. FPL is *NOT* public domain!   *
  21.  * Any provided source code is only for reference and for assurance     *
  22.  * that users should be able to compile FPL on any operating system     *
  23.  * he/she wants to use it in!                                           *
  24.  *                                                                      *
  25.  * You may not change, resource, patch files or in any way reverse      *
  26.  * engineer anything in the FPL package.                                *
  27.  *                                                                      *
  28.  * This program is distributed in the hope that it will be useful,      *
  29.  * but WITHOUT ANY WARRANTY; without even the implied warranty of       *
  30.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                 *
  31.  *                                                                      *
  32.  * Daniel Stenberg                                                      *
  33.  * Ankdammsgatan 36, 4tr                                                *
  34.  * S-171 43 Solna                                                       *
  35.  * Sweden                                                               *
  36.  *                                                                      *
  37.  * FidoNet 2:201/328    email:dast@sth.frontec.se                       *
  38.  *                                                                      *
  39.  ************************************************************************/
  40.  
  41. #ifdef AMIGA
  42. #include <exec/types.h>
  43. #include <proto/exec.h>
  44.  
  45. int CXBRK(void) { return(0); }  /* Disable Lattice/SAS CTRL/C handling */
  46. int chkabort(void) { return(0); }  /* really */
  47. #ifdef SHARED
  48. #include <exec/libraries.h>
  49. #include <libraries/dos.h>
  50.  
  51. #include "/include/pragmas/FPL_pragmas.h"
  52. #include "/include/clib/FPL_protos.h"
  53. #include "FPL.h"
  54. struct Library *FPLBase = NULL;
  55. #endif
  56.  
  57. #define REG(x) register __ ## x
  58.  
  59. #elif defined(UNIX) /* #ifdef AMIGA */
  60. #include <sys/types.h>
  61.  
  62. #if defined(__GCC_NEW_VARARGS__) /* && defined(__GCC__) */
  63. /*
  64.  * If you want this file to be compiled using the va_* macros instead of the
  65.  * dirty "address of parameter version", define as below!
  66.  * (Without this define, SunOS 4.1.x versions will likely crash!)
  67.  */
  68.  
  69. #define VARARG_FUNCTIONS /* should be defined before the includes below */
  70. #endif
  71.  
  72.  
  73. #define REG(x)
  74. #define TRUE  1
  75. #define FALSE 0
  76. #include "../include/libraries/FPL.h"
  77. #include "../include/clib/FPL_protos.h"
  78.  
  79.  
  80. #endif
  81.  
  82. #include <stdlib.h>
  83. #include <string.h>
  84. #include <stdio.h>
  85. #include <stdarg.h>
  86.  
  87. #if defined(AMIGA) && defined(SHARED)
  88. #define CALLER __saveds
  89. #define ASM __asm
  90. #else
  91. #define CALLER
  92. #define ASM
  93. #endif
  94.  
  95. long ASM func(REG(a0) struct fplArgument *);
  96. long ASM inter(REG(a0) void *);
  97. void CALLER ASM MyFree(REG(a1) void *, REG(d0) long);
  98. void CALLER ASM *MyAlloc(REG(d0) long);
  99. long ASM newline(REG(a0) void *);
  100.  
  101. int memory_counter=0;
  102. int maxmemory_counter=0;
  103. int mallocs=0;
  104.  
  105. int newlines=0;
  106.  
  107. enum myfunctions {
  108.   FN_GETINT,
  109.   FN_GETSTRING,
  110.   FN_OUTPUT,
  111.   FN_EXECUTE,
  112.   FN_PRINTF,
  113.   FN_TEST,
  114.   FN_OPENL,
  115.   FN_CLOSEL
  116.   };
  117.  
  118. /**********************************************************************
  119.  *
  120.  * int main(int, char **)
  121.  *
  122.  * This function is not included in the run time library version.
  123.  *
  124.  ******/
  125.  
  126. void *key;
  127.  
  128. int main(int argc, char **argv)
  129. {
  130.   long n, end=0;
  131.   long count=0;
  132.   int pre_mallocs;
  133.   long pre_malloc;
  134.   struct fplSymbol *symbols;
  135.   long i;
  136.  
  137.  
  138. #if defined(SHARED) && defined(AMIGA)
  139.   if(!(FPLBase=OpenLibrary(FPLNAME, 5))) {
  140.     printf("Error opening %s!\n", FPLNAME);
  141.     return(-1);
  142.   }
  143.   printf("--> %s\n", FPLBase->lib_IdString);
  144. #endif
  145.  
  146.   if(argc<2) {
  147.     printf("Usage: SFPL <FPL program file name>\n");
  148. #if defined(AMIGA) && defined(SHARED)
  149.     CloseLibrary((struct Library *)FPLBase);
  150. #endif
  151.     return 0;
  152.   }
  153.  
  154.   key=fplInitTags(func,
  155.           FPLTAG_INTERVAL, (unsigned long)inter, /* interval func */
  156.           FPLTAG_USERDATA, (unsigned long)&count, /* user data */
  157.           FPLTAG_INTERNAL_DEALLOC, (unsigned long)MyFree,
  158.           FPLTAG_INTERNAL_ALLOC, (unsigned long)MyAlloc,
  159.           FPLTAG_NEWLINE_HOOK, (long)newline,
  160.           FPLTAG_CACHEALLFILES, FPLCACHE_EXPORTS,
  161.           FPLTAG_DONE);
  162.  
  163.   fplAddFunction(key, "getint",    FN_GETINT,    'I', "s", NULL);
  164.   fplAddFunction(key, "getstring", FN_GETSTRING, 'S', "s", NULL);
  165.   fplAddFunction(key, "output",       FN_OUTPUT,    'I', "O", NULL);
  166.   fplAddFunction(key, "executeFPL",FN_EXECUTE,   'I', "S", NULL);
  167.   fplAddFunction(key, "printf",    FN_PRINTF,    'I', "So>", NULL);
  168.   fplAddFunction(key, "Test",      FN_TEST,      'I', "SI", NULL);
  169.  
  170.   pre_mallocs=mallocs;
  171.   pre_malloc=memory_counter;
  172.  
  173. #ifdef HIJACK
  174.   end=fplExecuteFileTags(key, "cpp.FPL", FPLTAG_COMPILE, TRUE, FPLTAG_DONE);
  175.  
  176.   fplHijack(key, "__LINE__");
  177.   fplHijack(key, "__TIME__");
  178.   fplHijack(key, "__DATE__");
  179.   fplHijack(key, "__FILE__");
  180. #endif
  181.   if(!end && argc>1) {
  182.     char *string=NULL;
  183.     end=fplExecuteFileTags(key, argv[1],
  184.                FPLTAG_STRING_RETURN, &string,
  185.                            FPLTAG_DONE);
  186.     if(string) {
  187.       printf("The program returned '%s'\n", string);
  188.       fplFreeString(key, string);
  189.     }
  190.   }
  191.  
  192. #if 0  
  193.   fplSendTags(key, FPLSEND_GETSYMBOL_FUNCTIONS, &symbols, FPLSEND_DONE);
  194.   printf("\n---------------------\nAll exported functions:\n");
  195.   for(i=0; i<symbols->num; i++)
  196.     printf("%s ", symbols->array[i]);
  197.   fplSendTags(key, FPLSEND_GETSYMBOL_FREE, symbols, FPLSEND_DONE);
  198.  
  199.   fplSendTags(key, FPLSEND_GETSYMBOL_VARIABLES, &symbols, FPLSEND_DONE);
  200.   printf("\n---------------------\nAll exported variables:\n");
  201.   for(i=0; i<symbols->num; i++)
  202.     printf("%s ", symbols->array[i]);
  203.   fplSendTags(key, FPLSEND_GETSYMBOL_FREE, symbols, FPLSEND_DONE);
  204.  
  205.   fplSendTags(key, FPLSEND_GETSYMBOL_CACHEDFILES, &symbols, FPLSEND_DONE);
  206.   printf("\n---------------------\nAll cached files:\n");
  207.   for(i=0; i<symbols->num; i++)
  208.     printf("%s ", symbols->array[i]);
  209.   fplSendTags(key, FPLSEND_GETSYMBOL_FREE, symbols, FPLSEND_DONE);
  210. #endif
  211.  
  212.   fplSendTags(key,
  213.           FPLSEND_GETRETURNCODE, &n,
  214.           FPLSEND_FLUSHFILE, 0,
  215.           FPLSEND_FLUSHCACHE, 1,
  216.           FPLSEND_DONE);
  217.  
  218.   fplFree(key); /* free all shit FPL uses internally */
  219.  
  220. #if defined(AMIGA) && defined(SHARED)
  221.   CloseLibrary((struct Library *)FPLBase);
  222. #endif
  223.   
  224.   printf("\n-----------------------------------------\n");
  225.   printf("Return code   :  %d\n", n);
  226.   printf("Interval func :  %d\n", count);
  227.   printf("Newlines      :  %d\n", newlines);
  228.   printf("Pre mallocs   :  %d\n", pre_mallocs);
  229.   printf("Pre memory use:  %d\n", pre_malloc);
  230.   printf("Malloc        :  %d\n", mallocs-pre_mallocs);
  231.   printf("memory use    :  %d\n", maxmemory_counter-pre_malloc);
  232.   printf("Not freed mem :  %d\n", memory_counter);
  233.   printf("-----------------------------------------\n");
  234.  
  235.   return end;
  236. }
  237.  
  238. #ifndef AMIGA /* if not using SAS/C on Amiga */
  239.  
  240. /******************************************************/
  241. /* Parameter list frontends of the library functions: */
  242. /******************************************************/
  243.  
  244. #if VARARG_FUNCTIONS
  245.  
  246. /*
  247.  * The following stub functions to the actual library functions was done
  248.  * to make this run under SunOS 4.1.x using gcc. Thanks to Bernd Noll
  249.  * (b_noll@sun.rhrk.un) for this contribution!
  250.  */
  251.  
  252. long fplExecuteScriptTags(void *anchor, char **program, long lines, ...)
  253. {
  254.   va_list tags;
  255.   long ret;
  256.   va_start(tags, lines); /* get parameter list */
  257.   ret = fplExecuteScript(anchor, program, lines, (unsigned long *)tags);
  258.   va_end(tags)
  259.   return ret;
  260. }
  261.  
  262. long fplExecuteFileTags(void *anchor, char *program, ...)
  263. {
  264.   va_list tags;
  265.   long ret;
  266.   va_start(tags, program); /* get parameter list */
  267.   ret = fplExecuteFile(anchor, program, (unsigned long *)tags);
  268.   va_end(tags)
  269.   return ret;
  270. }
  271.  
  272. void *fplInitTags(long (*func)(struct fplArgument *), ...)
  273. {
  274.   va_list tags;
  275.   long ret;
  276.   va_start(tags, func); /* get parameter list */
  277.   ret = fplInit(func, (unsigned long *)tags);
  278.   va_end(tags)
  279.   return ret;
  280. }
  281.  
  282. long fplResetTags(void *anchor, ...)
  283. {
  284.   va_list tags;
  285.   long ret;
  286.   va_start(tags, anchor); /* get parameter list */
  287.   ret = fplReset(anchor, (unsigned long *)tags);
  288.   va_end(tags)
  289.   return ret;
  290. }
  291.  
  292. long fplSendTags(void *anchor, ...)
  293. {
  294.   va_list tags;
  295.   long ret;
  296.   va_start(tags, anchor); /* get parameter list */
  297.   ret = fplSend(anchor, (unsigned long *)tags);
  298.   va_end(tags)
  299.   return ret;
  300. }
  301.  
  302. long fplAddFunctionTags(void *anchor, char *name, long ID, char rtrn,
  303.                         char *format, ...)
  304. {
  305.   va_list tags;
  306.   long ret;
  307.   va_start(tags, format); /* get parameter list */
  308.   ret = fplAddFunction(anchor, name, ID, rtrn, format, (unsigned long *)tags);
  309.   va_end(tags)
  310.   return ret;
  311. }
  312.  
  313. #else /* VARARG_FUNCTIONS */
  314.  
  315. long fplExecuteScriptTags(void *anchor, char **program, long lines,
  316.                           unsigned long tags, ...)
  317. {
  318.   return(fplExecuteScript(anchor, program, lines, (unsigned long *)&tags));
  319. }
  320.  
  321. long fplExecuteFileTags(void *anchor, char *program, unsigned long tags, ...)
  322. {
  323.   return(fplExecuteFile(anchor, program, (unsigned long *)&tags));
  324. }
  325.  
  326. void *fplInitTags(long (*func)(struct fplArgument *), unsigned long tags, ...)
  327. {
  328.   return(fplInit(func, (unsigned long *)&tags));
  329. }
  330.  
  331. long fplResetTags(void *anchor, unsigned long tags, ...)
  332. {
  333.   return(fplReset(anchor, &tags));
  334. }
  335.  
  336. long fplSendTags(void *anchor, unsigned long tags, ...)
  337. {
  338.   return(fplSend(anchor, &tags));
  339. }
  340.  
  341. long fplAddFunctionTags(void *anchor, char *name, long ID, char rtrn,
  342.                         char *format, unsigned long tags, ...)
  343. {
  344.   return(fplAddFunction(anchor, name, ID, rtrn, format, &tags));
  345. }
  346.  
  347. #endif
  348.  
  349. #endif
  350.  
  351. long ASM func(REG(a0) struct fplArgument *arg)
  352. {
  353.   int ret;
  354.   long col;
  355.   char *name;
  356.   char *string;
  357.   void *anchor=arg->key;
  358.   char systemline[80];
  359.   switch(arg->ID) {
  360.   case FN_PRINTF:
  361. #if defined(AMIGA)
  362.     vprintf(arg->argv[0], (char *)&arg->argv[1]);
  363. #elif defined(UNIX)
  364.     vfprintf(stderr, arg->argv[0], (char *)&arg->argv[1]);
  365. #endif
  366.     break;
  367.   case FN_OUTPUT: /* output */
  368.     if(arg->format[0]==FPL_STRARG)  /* we got a string! */
  369.       string="%s";
  370.     else
  371.       string="%d";
  372. #if defined(AMIGA)
  373.     printf(string, arg->argv[0]);
  374. #elif defined(UNIX)
  375.     fprintf(stderr, string, arg->argv[0]);
  376. #endif
  377.     fplSendTags(anchor, FPLSEND_INT, 1, FPLSEND_DONE);
  378. #if 0
  379.     if(count++>10)
  380.       return(FPLERR_PROGRAM_STOPPED);
  381. #endif
  382.     break;
  383.   case FN_GETSTRING:
  384.     if(string=(char *)fplAlloc(anchor, 64)) {
  385.       if(arg->argc)
  386.     printf("%s", arg->argv[0]);
  387.       fgets(string, 64, stdin);
  388.       ret=fplSendTags(arg->key,
  389.               FPLSEND_STRING, string,
  390.               FPLSEND_STRLEN, strlen(string)-1,
  391.               FPLSEND_DONE);
  392.       fplDealloc(anchor, string);
  393.     } else
  394.       ret=FPLERR_OUT_OF_MEMORY;
  395.     return(ret);
  396.  
  397.   case FN_EXECUTE:
  398.     ret=fplExecuteFile(anchor, arg->argv[0], NULL);
  399.     return(ret);
  400.     break;
  401.  
  402. #ifdef HIJACK
  403.   /*
  404.    * Not implemented, and not subject to either in the nearest future!
  405.    */
  406.   case FPL_HIJACK_READ:
  407.     if(!strcmp("__LINE__", arg->name)) {
  408.       fplSendTags(anchor, FPLSEND_GETVIRLINE, &col, FPLSEND_DONE);
  409.       fplSendTags(anchor, FPLSEND_INT, col, FPLSEND_DONE);
  410.     } else if(!strcmp("__FILE__", arg->name)) {
  411.       fplSendTags(anchor, FPLSEND_GETVIRFILE, &name, FPLSEND_DONE);
  412.       if(*name=='\"') {
  413.     name++;
  414.     col=0;
  415.     while(name[col] && name[col]!='\"')
  416.       col++;
  417.       } else
  418.     col=-1;
  419.       fplSendTags(anchor, FPLSEND_STRING, name,
  420.           FPLSEND_STRLEN, col, FPLSEND_DONE);
  421.     } else
  422.       fprintf(stderr, "%s variable read!\n", arg->name);
  423.     break;
  424. #endif
  425.   case FPL_GENERAL_ERROR:
  426.     {
  427.       char buffer[FPL_ERRORMSG_LENGTH];
  428.       fplSendTags(anchor,
  429.           FPLSEND_GETVIRLINE, &col,
  430.           FPLSEND_GETVIRFILE, &name,
  431.           FPLSEND_DONE);
  432.       if(*name=='\"') {
  433.     ret=0;
  434.     name++;
  435.     while(name[ret] && name[ret]!='\"')
  436.       ret++;
  437.     string=(char *)fplAlloca(anchor, ret+1);
  438.     memcpy(string, name, ret);
  439.     string[ret]='\0';
  440.       } else {
  441.     string=name;
  442.     ret=0;
  443.       }
  444.       printf("\n>>> %s\n",
  445.          fplGetErrorMsg(arg->key, (long)arg->argv[0], buffer));
  446.       printf(">>> Line %d in file \"%s\". <<<\n", col, string);
  447.       if(ret)
  448.     fplDealloca(anchor, string);
  449.     }
  450.     break;
  451.   case FPL_UNKNOWN_FUNCTION:
  452.     col=22; /* only to breakpoint */
  453.     break;
  454. #ifdef COMPILE_AVAIL
  455.   case FPL_COMPILE: /* for experiments! */
  456.     if(arg->format[0]==FPL_STRARG)
  457.       printf("%s", (char *)arg->funcdata);
  458.     else
  459.       printf("%d", (int)arg->funcdata);
  460.     break;
  461. #endif
  462.   case FN_GETINT:
  463.     if(arg->argc)
  464.       printf("%s", (char *)arg->argv[0]);
  465.     scanf("%d", &ret);
  466.     ret=fplSendTags(anchor, FPLSEND_INT, ret, FPLSEND_DONE);
  467.     return(ret);
  468.   }
  469.   return(0);
  470. }
  471.  
  472. long ASM inter(REG(a0) void *count)
  473. {
  474.   static line=-1;
  475. #if 0
  476.   static char *name;
  477.   long current_line;
  478.   char *curr_name;
  479.  
  480.   fplSendTags(key, FPLSEND_GETVIRLINE, ¤t_line, FPLSEND_DONE);
  481.   fplSendTags(key, FPLSEND_GETVIRFILE, &curr_name, FPLSEND_DONE);
  482.   if(line!=current_line || name != curr_name) {
  483.     line=current_line;
  484.     name=curr_name;
  485. /*    fprintf(stderr, " < %d %s > ", line, name?name:"unknwon"); */
  486.   }
  487. #endif
  488.  
  489.   (*(int *)count)++; /* just to count the number of times this routine has been
  490.             called. */
  491.   return(0);
  492. }
  493.  
  494. void CALLER ASM MyFree(REG(a1) void *pntr, REG(d0) long size)
  495. {
  496.   memory_counter-=size;
  497.   memset(pntr, 0xaa, size); /* mess up this area before free! */
  498.   free(pntr);
  499. }
  500.  
  501. long ASM newline(REG(a0) void *anchor)
  502. {
  503.   /* just for fun! */
  504.   newlines++;
  505.   return(0);
  506. }
  507.  
  508. void CALLER ASM *MyAlloc(REG(d0) long size)
  509. {
  510.   void *mem;
  511.   mallocs++;
  512.   if((memory_counter+=size)>maxmemory_counter)
  513.     maxmemory_counter=memory_counter;
  514. #ifdef UNIX
  515.   mem=malloc(size);
  516. #else
  517.   mem=AllocMem(size, 0);
  518. #endif
  519.   if(mem)
  520.     memset(mem, 0xaa, size); /* mess up this area before free! */
  521.   return (mem);
  522. }
  523.